#pragma once

#include <iostream>
#include <string>
#include "Log.hpp"
#include <signal.h>
#include <functional>
#include "Socket.hpp"

using func_t = std::function<std::string(std::string &in)>;
//using定义类型别名
extern Log lg;

class Tcpserver
{
public:
    Tcpserver(uint16_t port_,func_t Callback_fun)
        :_port(port_)
        ,_Callback_fun(Callback_fun)
    {}

    void Init()
    {
        _listenfd.Getsocket();
        _listenfd.Getbind(_port);
        _listenfd.Getlisten();

        lg(Info,"tcpserver init success");
    }

    void Start()
    {
        signal(SIGCHLD,SIG_IGN);
        signal(SIGPIPE,SIG_IGN);

        while(true)
        {
            std::string clientip;
            uint16_t clientport;
            int socketfd = _listenfd.Getaccept(&clientip,&clientport);
            if(socketfd<0)continue;
            lg(Info,"accept success , clientip: %s,port: %d",clientip.c_str(),clientport);
            
            if(fork() == 0)
            {
                _listenfd.Close();
                std::string str_stream;
                while(true)
                {
                    char buffer[256];
                    int n =read(socketfd,buffer,sizeof(buffer));
                    if(n>0)
                    {
                        buffer[n]=0;
                        str_stream+=buffer;

                        lg(Debug,"debug is : %s",str_stream.c_str());

                        std::string temp = _Callback_fun(str_stream);

                        if (temp.empty())continue;;

                        write(socketfd,temp.c_str(),temp.size());   
                    }
                    else break;
                }
                exit(0);
            }
            close(socketfd);
        }
    }

    ~Tcpserver()
    {}
private:
    Socket _listenfd;
    uint16_t _port;
    func_t _Callback_fun;
};